﻿
using Scaffold.AppService.Interfaces;
using Scaffold.AppService.Model.RequestModel;
using Scaffold.Domain;
using Scaffold.Domain.Model;
using EStart.DataBase.EF;
using EStart.DataBase.Event.Domian;
using EStart.Infrastructure.ClientData;
using QuestionBank.Infrastructure.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Scaffold.AppService.Model.Messaging;
using Scaffold.AppService.Model.ResponseModel;
using EStart.Infrastructure.Domain;
using Microsoft.EntityFrameworkCore;
using EStart.Infrastructure.Extensions;
using Scaffold.AppService.Extensions;

namespace Scaffold.AppService.Implements
{
    public partial class UserService : ServiceCore<User>, IUserService
    {
        private readonly IDepartmentService _departmentService;
        private readonly IUserInRoleGroupService _userInRoleGroupService;
        private readonly IUserMenuOrActionInRoleService _userMenuOrActionInRoleService;
        private readonly IRoleInRoleGroupService _roleInRoleGroupService;
        private readonly IUserMenuService _userMenuService;
        public UserService(
            ScaffoldDbContext context,
            EventDbContext eventDbContext,
            IDepartmentService departmentService,
            IUserInRoleGroupService userInRoleGroupService,
            IUserMenuOrActionInRoleService userMenuOrActionInRoleService,
            IRoleInRoleGroupService roleInRoleGroupService,
            IUserMenuService userMenuService
            ) : base(context, eventDbContext)
        {
            _departmentService = departmentService;
            _userInRoleGroupService = userInRoleGroupService;
            _userMenuOrActionInRoleService = userMenuOrActionInRoleService;
            _roleInRoleGroupService = roleInRoleGroupService;
            _userMenuService = userMenuService;
        }

        public ApiResult<string> Delete(Guid guid)
        {
            ApiResult<string> response = new ApiResult<string>();
            try
            {

                var school = Query().Where(n => n.Guid == guid).FirstOrDefault();
                if (school == null)
                {
                    response.message = "未找到改数据！";
                    return response;
                }
                DeleteForge(school);
                var b = _unitofwork.Commit();
                response.success = b;
                response.message = b ? "删除成功！" : "删除失败！";
                return response;
            }
            catch (Exception ex)
            {
                response.message = "删除失败！意外错误:" + ex.Message;
                return response;
            }
        }

        public ApiResult<UserResponse> GetDetail(Guid guid)
        {
            ApiResult<UserResponse> response = new ApiResult<UserResponse>();
            try
            {

                var entity = Query().Where(n => n.Guid == guid)
                    .Include(n => n.Department)
                    .Select(n => new UserResponse
                    {
                        CreateTime = n.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"),
                        guid = n.Guid.ToString(),
                        LockoutEnabled = n.LockoutEnabled,
                        LoginName = n.LoginName,
                        Mobile = n.Mobile,
                        Password = n.Password.DESDecrypt(),
                        RealName = n.RealName,
                        SchoolGuid = n.Department.Guid.ToString(),
                        Tel = n.Tel,
                        RoleGroup = n.UserRoleGroup.Select(c => c.RoleGroupID).ToList()
                    }).FirstOrDefault();

                if (entity == null)
                {
                    response.message = "未找到改数据！";
                    return response;
                }
                response.success = true;
                response.data = entity;
                response.message = "获取成功！";
                return response;
            }
            catch (Exception ex)
            {
                response.message = "获取失败！意外错误:" + ex.Message;
                return response;
            }
        }

        public async Task<ApiResult<Page<UserResponse>>> GetPagesAsync(UserPage request)
        {
            ApiResult<Page<UserResponse>> response = new ApiResult<Page<UserResponse>>();
            try
            {
                var pages = await Query()
                            .HasWhere(request.LoginName, n => n.LoginName.Contains(request.LoginName))
                            .HasWhere(request.Mobile, n => n.Mobile.Contains(request.Mobile))
                            .HasWhere(request.RealName, n => n.RealName.Contains(request.RealName))
                            .Select(n => new UserResponse
                            {
                                CreateTime = n.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"),
                                guid = n.Guid.ToString(),
                                LockoutEnabled = n.LockoutEnabled,
                                LoginName = n.LoginName,
                                Mobile = n.Mobile,
                                Password = n.Password.DESDecrypt(),
                                RealName = n.RealName,
                                SchoolGuid = n.Department.Guid.ToString(),
                                Tel = n.Tel,
                                SchoolName = n.Department.Name
                            }).OrderByDescending(n => n.CreateTime).ToPageAsync(request.PageIndex, request.PageSize);

                response.success = true;
                response.message = "获取成功！";
                response.data = pages;
                return response;

            }
            catch (Exception ex)
            {
                response.message = "获取失败！意外错误：" + ex.Message;
                return response;
            }
        }
        public async Task<IList<LoginMenu>> GetMenusByGuidAsync(Guid guid)
        {
            var entity = Query().FirstOrDefault(p => p.Guid == guid);
            // 读取用户角色组 ids
            var roleGroupIds = await _userInRoleGroupService.Query().Where(p => p.UserID == entity.ID).Select(p => p.RoleGroupID).ToListAsync();
            // 读取角色 ids
            var roleIds = await _roleInRoleGroupService.Query()
                .Where(p => roleGroupIds.Contains(p.RoleGroupID))
                .GroupBy(p => p.RoleID)
                .Select(p => p.FirstOrDefault().RoleID)
                .ToListAsync();
            // 读取菜单
            var menus = await _userMenuOrActionInRoleService.Query().Include(n => n.UserAction)
                .Include(n => n.UserMenu)
                .Where(p => roleIds.Contains(p.RoleID)).ToListAsync();
            // 将菜单分组
            var menusGroups = menus.GroupBy(p => p.UserMenuID);
            // 
            var loginMenus = new List<LoginMenu>();
            // 获取一级菜单的id列表
            var oneLevelMenuIds = new List<int>();
            foreach (var groups in menusGroups)
            {
                oneLevelMenuIds.Add(groups.FirstOrDefault().FatherMenuID);
            }
            // 获取一级菜单信息
            var oneLevelMenus = await _userMenuService.Query().Where(p => oneLevelMenuIds.Contains(p.ID)).ToListAsync();
            // 添加到要返回的菜单列表中
            loginMenus = oneLevelMenus.Select(p => new LoginMenu
            {
                Id = p.ID,
                MenuName = p.Name,
                Url = p.Url
            }).ToList();

            var childrenLoginMenu = new List<LoginMenu>();
            foreach (var groups in menusGroups)
            {
                // 获取菜单
                var menu = groups.FirstOrDefault().UserMenu;
                // 获取菜单下对应的操作动作
                var actionGroup = menus.Where(p => p.UserMenuID == menu.ID).GroupBy(p => p.UserActionID).ToList();
                childrenLoginMenu.Add(new LoginMenu
                {
                    Actions = actionGroup.Select(p =>
                    {
                        var a = p.FirstOrDefault().UserAction;
                        return new LoginAction
                        {
                            ActionName = a.Name,
                            Parameter = a.Parameter
                        };
                    }).ToList(),
                    MenuName = menu.Name,
                    Id = menu.ID,
                    Url = menu.Url,
                    ParentId = menu.UserMenuID.Value
                });
            }
            // 将菜单添加到对应的父菜单
            foreach (var item in childrenLoginMenu.GroupBy(p => p.ParentId))
            {
                var parentId = item.FirstOrDefault().ParentId;
                var menu = loginMenus.FirstOrDefault(p => p.Id == parentId);
                if (menu != null)
                {
                    menu.Children = item.ToList();
                }
            }

            return loginMenus;
        }

        public async Task<ApiResult<LoginResponse>> LoginAsync(LoginRequest request)
        {
            var response = new ApiResult<LoginResponse>
            {
                statusCode = 200
            };
            try
            {
                var entity = await Query().FirstOrDefaultAsync(p => p.LoginName == request.LoginName);
                if (entity == null || entity.Password != request.Password.DESEncrypt())
                {
                    response.message = "帐户或密码错误.";
                    return response;
                }
                var data = new LoginResponse
                {
                    Guid = entity.Guid,
                    LoginName = entity.LoginName,
                    RealName = entity.RealName
                };

                data.Menus = await GetMenusByGuidAsync(entity.Guid);

                response.message = "登录成功.";
                response.success = true;
                response.data = data;
            }
            catch (Exception ex)
            {
                response.message = ex.Message;
                response.statusCode = 500;
            }
            return response;
        }
        public async Task<ApiResult<string>> SaveAsync(UserRequest request)
        {
            ApiResult<string> response = new ApiResult<string>();
            try
            {
                if (string.IsNullOrEmpty(request.guid))
                {
                    var user = Query().Where(n => n.LoginName == request.LoginName || n.Mobile == request.Mobile).FirstOrDefault();
                    if (user != null)
                    {
                        throw new Exception("已存在该登录名或者手机号！");
                    }
                    var schoolGuid = Guid.Parse(request.SchoolGuid);
                    User admin = new User();
                    admin.LoginName = request.LoginName;
                    admin.Password = request.Password.DESEncrypt();
                    admin.RealName = request.RealName;
                    admin.Mobile = request.Mobile;
                    admin.Tel = request.Tel;
                    admin.Department = await _departmentService.Query().Where(n => n.Guid == schoolGuid).FirstOrDefaultAsync();

                    admin.UserRoleGroup = new List<UserInRoleGroup>();
                    if (request.RoleGroup != null)
                    {
                        //新增不存在的角色组
                        foreach (var item in request.RoleGroup)
                        {
                            admin.UserRoleGroup.Add(new UserInRoleGroup()
                            {
                                UserID = admin.ID,
                                RoleGroupID = item
                            });
                        }

                    }
                    await _unitofwork.RegisterNewAsync(admin);
                }
                else
                {
                    var schoolGuid = Guid.Parse(request.SchoolGuid);
                    var userguid = Guid.Parse(request.guid);
                    var olduser = Query().Include(n => n.UserRoleGroup)
                        .Where(n => n.Guid == userguid)
                        .FirstOrDefault();
                    if (olduser == null)
                    {
                        throw new Exception("未找到修改数据！！");
                    }
                    var simpleuser = Query().Where(n => n.LoginName == request.LoginName || n.Mobile == request.Mobile)
                        .Where(n => n.Guid != userguid).FirstOrDefault();
                    if (simpleuser != null)
                    {
                        throw new Exception("已存在该登录名或者手机号！");
                    }
                    olduser.LoginName = request.LoginName;
                    olduser.Password = request.Password.DESEncrypt();
                    olduser.RealName = request.RealName;
                    olduser.Mobile = request.Mobile;
                    olduser.Tel = request.Tel;
                    olduser.Department = await _departmentService.Query().Where(n => n.Guid == schoolGuid).FirstOrDefaultAsync();

                    if (olduser.UserRoleGroup == null)
                    {
                        olduser.UserRoleGroup = new List<UserInRoleGroup>();
                    }
                    if (request.RoleGroup != null)
                    {
                        //新增不存在的角色组
                        foreach (var item in request.RoleGroup)
                        {
                            var rolegroup = olduser.UserRoleGroup.Where(n => n.RoleGroupID == item).FirstOrDefault();
                            if (rolegroup == null)
                            {
                                await _unitofwork.RegisterNewAsync(new UserInRoleGroup()
                                {
                                    UserID = olduser.ID,
                                    RoleGroupID = item
                                });
                            }
                        }
                        //删除移除的
                        foreach (var item in olduser.UserRoleGroup)
                        {
                            var delrole = request.RoleGroup.Where(n => n == item.RoleGroupID).Count();
                            if (delrole == 0)
                            {
                                _unitofwork.RegisterDeleted(item);
                            }
                        }
                    }
                    _unitofwork.RegisterDirty(olduser);


                }

                var b = await _unitofwork.CommitAsync();

                response.success = b;
                response.message = b ? "保存成功！" : "保存失败";
                return response;
            }
            catch (Exception ex)
            {

                response.message = "发生错误：" + ex.Message;
                return response;
            }
        }
    }
}
